// 独立的LSP管理器测试，不依赖其他有问题的crate

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::{Mutex, RwLock};
use tokio::time::interval;
use uuid::Uuid;

/// LSP服务器状态
#[derive(Debug, Clone, PartialEq)]
pub enum LspServerStatus {
    NotStarted,
    Starting,
    Running,
    Stopping,
    Stopped,
    Error(String),
    Crashed,
}

/// LSP服务器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LspServerConfig {
    pub name: String,
    pub command: String,
    pub args: Vec<String>,
    pub file_extensions: Vec<String>,
    pub language_ids: Vec<String>,
    pub enabled: bool,
    pub auto_restart: bool,
    pub max_restart_count: u32,
    pub restart_interval: u64,
    pub health_check_interval: u64,
}

impl Default for LspServerConfig {
    fn default() -> Self {
        Self {
            name: String::new(),
            command: String::new(),
            args: Vec::new(),
            file_extensions: Vec::new(),
            language_ids: Vec::new(),
            enabled: true,
            auto_restart: true,
            max_restart_count: 3,
            restart_interval: 5,
            health_check_interval: 30,
        }
    }
}

/// 全局LSP设置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GlobalLspSettings {
    pub enable_diagnostics: bool,
    pub enable_completion: bool,
    pub max_completion_items: usize,
    pub diagnostic_delay_ms: u64,
    pub max_concurrent_servers: usize,
    pub server_startup_timeout: u64,
    pub request_timeout_ms: u64,
}

impl Default for GlobalLspSettings {
    fn default() -> Self {
        Self {
            enable_diagnostics: true,
            enable_completion: true,
            max_completion_items: 100,
            diagnostic_delay_ms: 500,
            max_concurrent_servers: 10,
            server_startup_timeout: 30,
            request_timeout_ms: 5000,
        }
    }
}

/// LSP管理器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LspManagerConfig {
    pub servers: HashMap<String, LspServerConfig>,
    pub global_settings: GlobalLspSettings,
}

impl Default for LspManagerConfig {
    fn default() -> Self {
        let mut servers = HashMap::new();

        // Python服务器配置
        servers.insert("python".to_string(), LspServerConfig {
            name: "Python Language Server".to_string(),
            command: "pylsp".to_string(),
            args: vec![],
            file_extensions: vec![".py".to_string(), ".pyi".to_string()],
            language_ids: vec!["python".to_string()],
            ..Default::default()
        });

        // TypeScript服务器配置
        servers.insert("typescript".to_string(), LspServerConfig {
            name: "TypeScript Language Server".to_string(),
            command: "typescript-language-server".to_string(),
            args: vec!["--stdio".to_string()],
            file_extensions: vec![".ts".to_string(), ".tsx".to_string(), ".js".to_string(), ".jsx".to_string()],
            language_ids: vec!["typescript".to_string(), "javascript".to_string()],
            ..Default::default()
        });

        // Rust服务器配置
        servers.insert("rust".to_string(), LspServerConfig {
            name: "Rust Analyzer".to_string(),
            command: "rust-analyzer".to_string(),
            args: vec![],
            file_extensions: vec![".rs".to_string()],
            language_ids: vec!["rust".to_string()],
            ..Default::default()
        });

        Self {
            servers,
            global_settings: GlobalLspSettings::default(),
        }
    }
}

impl LspManagerConfig {
    pub fn get_server_for_extension(&self, extension: &str) -> Option<&LspServerConfig> {
        self.servers.values().find(|config| {
            config.enabled && config.file_extensions.contains(&extension.to_string())
        })
    }

    pub fn get_server_for_language(&self, language_id: &str) -> Option<&LspServerConfig> {
        self.servers.values().find(|config| {
            config.enabled && config.language_ids.contains(&language_id.to_string())
        })
    }

    pub fn get_enabled_servers(&self) -> Vec<(&String, &LspServerConfig)> {
        self.servers.iter().filter(|(_, config)| config.enabled).collect()
    }
}

/// 资源使用统计
#[derive(Debug, Default, Clone)]
pub struct ResourceStats {
    pub cpu_usage: f64,
    pub memory_usage: u64,
    pub requests_handled: u64,
    pub avg_response_time: f64,
    pub error_count: u64,
}

/// LSP服务器实例信息
#[derive(Debug)]
pub struct LspServerInstance {
    pub id: String,
    pub language: String,
    pub config: LspServerConfig,
    pub status: LspServerStatus,
    pub started_at: Option<Instant>,
    pub last_activity: Instant,
    pub restart_count: u32,
    pub last_health_check: Instant,
    pub resource_stats: ResourceStats,
}

/// 简化的LSP服务器管理器
pub struct SimpleLspServerManager {
    config: Arc<RwLock<LspManagerConfig>>,
    servers: Arc<Mutex<HashMap<String, LspServerInstance>>>,
    running: Arc<Mutex<bool>>,
}

impl SimpleLspServerManager {
    pub fn new(config: LspManagerConfig) -> Self {
        Self {
            config: Arc::new(RwLock::new(config)),
            servers: Arc::new(Mutex::new(HashMap::new())),
            running: Arc::new(Mutex::new(false)),
        }
    }

    pub async fn start(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut running = self.running.lock().await;
        if *running {
            return Ok(());
        }
        *running = true;
        Ok(())
    }

    pub async fn stop(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut running = self.running.lock().await;
        if !*running {
            return Ok(());
        }
        *running = false;
        
        let mut servers = self.servers.lock().await;
        servers.clear();
        Ok(())
    }

    pub async fn discover_server_for_file(&self, file_path: &str) -> Option<String> {
        let extension = std::path::Path::new(file_path)
            .extension()
            .and_then(|ext| ext.to_str())
            .map(|ext| format!(".{}", ext))?;

        let config = self.config.read().await;
        for (language, server_config) in &config.servers {
            if server_config.enabled && server_config.file_extensions.contains(&extension) {
                return Some(language.clone());
            }
        }

        None
    }

    pub async fn get_config(&self) -> LspManagerConfig {
        let config = self.config.read().await;
        config.clone()
    }

    pub async fn update_config(&self, new_config: LspManagerConfig) {
        let mut config = self.config.write().await;
        *config = new_config;
    }

    pub async fn get_all_server_status(&self) -> HashMap<String, LspServerStatus> {
        let servers = self.servers.lock().await;
        servers.iter()
            .map(|(lang, server)| (lang.clone(), server.status.clone()))
            .collect()
    }
}

// 测试用例
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_config_creation() {
        let config = LspManagerConfig::default();
        
        // 检查全局设置
        assert!(config.global_settings.enable_diagnostics);
        assert!(config.global_settings.enable_completion);
        assert_eq!(config.global_settings.max_completion_items, 100);
        assert_eq!(config.global_settings.diagnostic_delay_ms, 500);
        
        // 检查默认服务器配置
        assert!(config.servers.contains_key("python"));
        assert!(config.servers.contains_key("typescript"));
        assert!(config.servers.contains_key("rust"));
    }

    #[test]
    fn test_server_config_defaults() {
        let config = LspServerConfig::default();
        
        assert!(config.enabled);
        assert!(config.auto_restart);
        assert_eq!(config.max_restart_count, 3);
        assert_eq!(config.restart_interval, 5);
        assert_eq!(config.health_check_interval, 30);
        assert!(config.file_extensions.is_empty());
        assert!(config.language_ids.is_empty());
    }

    #[test]
    fn test_get_server_for_extension() {
        let config = LspManagerConfig::default();
        
        // 测试Python文件
        let python_server = config.get_server_for_extension(".py");
        assert!(python_server.is_some());
        assert_eq!(python_server.unwrap().command, "pylsp");
        
        // 测试TypeScript文件
        let ts_server = config.get_server_for_extension(".ts");
        assert!(ts_server.is_some());
        assert_eq!(ts_server.unwrap().command, "typescript-language-server");
        
        // 测试Rust文件
        let rust_server = config.get_server_for_extension(".rs");
        assert!(rust_server.is_some());
        assert_eq!(rust_server.unwrap().command, "rust-analyzer");
        
        // 测试未知扩展名
        let unknown_server = config.get_server_for_extension(".unknown");
        assert!(unknown_server.is_none());
    }

    #[test]
    fn test_get_server_for_language() {
        let config = LspManagerConfig::default();
        
        // 测试Python语言
        let python_server = config.get_server_for_language("python");
        assert!(python_server.is_some());
        assert_eq!(python_server.unwrap().command, "pylsp");
        
        // 测试TypeScript语言
        let ts_server = config.get_server_for_language("typescript");
        assert!(ts_server.is_some());
        assert_eq!(ts_server.unwrap().command, "typescript-language-server");
        
        // 测试JavaScript语言（应该返回TypeScript服务器）
        let js_server = config.get_server_for_language("javascript");
        assert!(js_server.is_some());
        assert_eq!(js_server.unwrap().command, "typescript-language-server");
        
        // 测试未知语言
        let unknown_server = config.get_server_for_language("unknown");
        assert!(unknown_server.is_none());
    }

    #[tokio::test]
    async fn test_manager_creation() {
        let config = LspManagerConfig::default();
        let manager = SimpleLspServerManager::new(config);
        
        // 测试管理器创建成功
        assert!(manager.start().await.is_ok());
        assert!(manager.stop().await.is_ok());
    }

    #[tokio::test]
    async fn test_server_discovery() {
        let config = LspManagerConfig::default();
        let manager = SimpleLspServerManager::new(config);
        
        assert!(manager.start().await.is_ok());
        
        // 测试文件扩展名发现
        let python_server = manager.discover_server_for_file("test.py").await;
        assert_eq!(python_server, Some("python".to_string()));
        
        let rust_server = manager.discover_server_for_file("test.rs").await;
        assert_eq!(rust_server, Some("rust".to_string()));
        
        let unknown_server = manager.discover_server_for_file("test.unknown").await;
        assert_eq!(unknown_server, None);
        
        assert!(manager.stop().await.is_ok());
    }

    #[tokio::test]
    async fn test_config_operations() {
        let config = LspManagerConfig::default();
        let manager = SimpleLspServerManager::new(config.clone());
        
        // 测试获取配置
        let retrieved_config = manager.get_config().await;
        assert_eq!(retrieved_config.global_settings.enable_diagnostics, config.global_settings.enable_diagnostics);
        
        // 测试更新配置
        let mut new_config = config.clone();
        new_config.global_settings.enable_diagnostics = false;
        manager.update_config(new_config.clone()).await;
        
        let updated_config = manager.get_config().await;
        assert_eq!(updated_config.global_settings.enable_diagnostics, false);
    }

    #[test]
    fn test_config_serialization() {
        let config = LspManagerConfig::default();
        
        // 测试序列化
        let json_str = serde_json::to_string_pretty(&config).unwrap();
        assert!(!json_str.is_empty());
        assert!(json_str.contains("servers"));
        assert!(json_str.contains("global_settings"));
        assert!(json_str.contains("python"));
        assert!(json_str.contains("typescript"));
        
        // 测试反序列化
        let deserialized_config: LspManagerConfig = serde_json::from_str(&json_str).unwrap();
        assert_eq!(deserialized_config.servers.len(), config.servers.len());
        assert_eq!(deserialized_config.global_settings.enable_diagnostics, config.global_settings.enable_diagnostics);
    }
}
